package com.smedi.ismedi.organization.core.port.adapter.restful;


import com.smedi.ismedi.constructionproject.api.dto.response.ProjectBasicResponse;
import com.smedi.ismedi.organization.api.dto.request.OrganizationListQueryRequest;
import com.smedi.ismedi.organization.api.dto.request.ProjectOrganizationListQueryRequest;
import com.smedi.ismedi.organization.api.dto.request.ProjectOrganizationRequest;
import com.smedi.ismedi.organization.api.dto.request.TwoProjectOrganizationNodeRequest;
import com.smedi.ismedi.organization.api.dto.response.ProjectOrganizationResponse;
import com.smedi.ismedi.organization.api.dto.response.resp.OrganizationResp;
import com.smedi.ismedi.organization.api.dto.response.resp.ProjectOrganizationResp;
import com.smedi.ismedi.organization.api.feign.RemoteProjectOrganizationFeignApi;
import com.smedi.ismedi.organization.core.application.command.OrganizationListQueryCommand;
import com.smedi.ismedi.organization.core.application.command.ProjectOrganizationCommand;
import com.smedi.ismedi.organization.core.application.command.ProjectOrganizationListQueryCommand;
import com.smedi.ismedi.organization.core.application.query.ProjectOrganizationQueryService;
import com.smedi.ismedi.organization.core.application.query.vo.ProjectOrganizationVo;
import com.smedi.ismedi.organization.core.application.service.ProjectOrgManageApplicationService;
import com.smedi.ismedi.organization.core.domain.aggregatemodel.ProjectOrganization;
import com.smedi.ismedi.organization.core.domain.aggregatemodel.model.Organization;
import com.smedi.ismedi.organization.core.domain.aggregatemodel.model.ProjectOrganizationModel;
import com.smedi.ismedi.organization.core.infrastructure.constant.CustomError;
import com.smedi.ismedi.organization.core.port.adapter.convert.AdapterConverter;
import com.smedi.ismedi.organization.core.port.adapter.service.ConstructionProjectRemoteApiService;
import com.smedi.ismedi.web.starter.common.ResponseData;
import com.smedi.ismedi.web.starter.exception.LogicException;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@AllArgsConstructor
public class ProjectOrganizationManageController implements RemoteProjectOrganizationFeignApi {
    private final DozerUtil dozerUtil;

    private final AdapterConverter adapterConverter;

    private final ProjectOrgManageApplicationService projectOrgManageApplicationService;
    private final ProjectOrganizationQueryService projectOrganizationQueryService;
    private final ConstructionProjectRemoteApiService constructionProjectRemoteApiService;

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<ProjectOrganizationResponse> postSaveProjectOrganization(@RequestBody ProjectOrganizationRequest projectOrganizationRequest) {
        // 请求对象转为入参对象
        ProjectOrganizationCommand projectOrganizationCommand = dozerUtil.convertor(projectOrganizationRequest, ProjectOrganizationCommand.class);

        // 返回请求接口数据
        return new ResponseData<ProjectOrganizationResponse>().success(dozerUtil.convertor(projectOrgManageApplicationService.saveProjectOrganization(projectOrganizationCommand), ProjectOrganizationResponse.class));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Boolean> deleteProjectOrganization(Long projectOrganizationId) {
        projectOrgManageApplicationService.deleteProjectOrganization(projectOrganizationId);
        return new ResponseData<Boolean>().success(true);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<ProjectOrganizationResponse>> getProjectOrganizationTreeRootIsProjectOrganization(Long projectId) {

        List<ProjectOrganizationResponse> list = dozerUtil.convertor(projectOrganizationQueryService.getProjectOrganizationTree(projectId), ProjectOrganizationResponse.class);
        return new ResponseData<List<ProjectOrganizationResponse>>().success(list);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<ProjectOrganizationResponse> getProjectOrganizationTreeRootIsProject(Long projectId) {
        // 获取项目信息
        ProjectBasicResponse projectBasicResponse = constructionProjectRemoteApiService.getProjectBasicView(projectId);
        if (projectBasicResponse != null) {
            ProjectOrganizationResponse root = new ProjectOrganizationResponse()
                    .setShortName(projectBasicResponse.getProjectShortName())
                    .setFullName(projectBasicResponse.getProjectName())
                    .setProjectId(projectBasicResponse.getProjectId())
                    .setProjectOrganizationChildren(dozerUtil.convertor(projectOrganizationQueryService.getProjectOrganizationTree(projectId), ProjectOrganizationResponse.class));

            return new ResponseData<ProjectOrganizationResponse>().success(root);
        } else {
            throw LogicException.raise(CustomError.PROJECT_NOT_AVAILABLE);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<ProjectOrganizationResponse> getProjectOrganizationView(Long projectOrganizationId) {
        // 返回请求接口数据
        return new ResponseData<ProjectOrganizationResponse>().success(dozerUtil.convertor(projectOrganizationQueryService.getProjectOrganizationView(projectOrganizationId), ProjectOrganizationResponse.class));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Boolean> getCheckAvailable(Long projectOrganizationId) {
        return new ResponseData<Boolean>().success(projectOrgManageApplicationService.checkProjectOrganizationIsAvailable(projectOrganizationId));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<Long>> getProjectOrganizationChildrenProjectOrganizationIdList(Long projectOrganizationId) {
        return new ResponseData<List<Long>>().success(projectOrganizationQueryService.getProjectOrganizationChildrenIdList(projectOrganizationId));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Map<Long, String>> getProjectOrganizationChildrenMap(Long projectOrganizationId) {
        return new ResponseData<Map<Long, String>>().success(projectOrganizationQueryService.getProjectOrganizationChildrenMap(projectOrganizationId));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Boolean> getCheckProjectOrganizationCanBeConfigOrganization(Long projectOrganizationId) {
        return new ResponseData<Boolean>().success(projectOrgManageApplicationService.checkProjectOrganizationCanBeConfigOrganization(projectOrganizationId));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Boolean> getCheckProjectOrganizationIsExternalUnit(Long projectOrganizationId) {
        return new ResponseData<Boolean>().success(projectOrgManageApplicationService.checkProjectOrganizationIsExternalUnit(projectOrganizationId));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<ProjectOrganizationResponse>> getQueryProjectOrganizationList(List<Long> projectOrganizationIds) {
        List<ProjectOrganizationVo> list = projectOrganizationQueryService.getProjectOrganizationByProjectOrganizationIds(projectOrganizationIds);
        List<ProjectOrganizationResponse> responses = dozerUtil.convertor(list, ProjectOrganizationResponse.class);

        return new ResponseData<List<ProjectOrganizationResponse>>().success(responses);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<ProjectOrganizationResponse>> getQueryProjectOrganizationListByFullName(String fullName, Long projectId) {
        List<ProjectOrganizationVo> list = projectOrganizationQueryService.queryProjectOrganizationListByFullName(fullName, projectId);
        return new ResponseData<List<ProjectOrganizationResponse>>().success(dozerUtil.convertor(list, ProjectOrganizationResponse.class));
    }

    @Override
    public ResponseData<List<ProjectOrganizationResponse>> getQueryProjectOrganizationListByFullNameList(List<String> fullNameList) {
        List<ProjectOrganizationVo> list = projectOrganizationQueryService.queryProjectOrganizationListByFullNameList(fullNameList);
        return new ResponseData<List<ProjectOrganizationResponse>>().success(dozerUtil.convertor(list, ProjectOrganizationResponse.class));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<ProjectOrganizationResponse>> getQueryProjectOrganizationListByProjectId(Long projectId) {
        List<ProjectOrganizationVo> list = projectOrganizationQueryService.queryProjectOrganizationListByProjectId(projectId);
        return new ResponseData<List<ProjectOrganizationResponse>>().success(dozerUtil.convertor(list, ProjectOrganizationResponse.class));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<Long>> getParentProjectOrganizationIdsByProjectOrganizationId(Long projectOrganizationId) {
        return new ResponseData<List<Long>>().success(projectOrganizationQueryService.getParentProjectOrganizationIdsByProjectOrganizationId(projectOrganizationId));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<ProjectOrganizationResponse>> getProjectOrganizationByProjectIdAndSpecialType(Long projectId, List<String> specialTypes) {
        return new ResponseData<List<ProjectOrganizationResponse>>().success(dozerUtil.convertor(projectOrganizationQueryService.getProjectOrganizationByProjectIdAndSpecialTypes(projectId, specialTypes), ProjectOrganizationResponse.class));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<ProjectOrganizationResponse>> postExchangeTwoProjectOrganizationNodeSort(TwoProjectOrganizationNodeRequest twoProjectOrganizationNodeRequest) {
        projectOrgManageApplicationService.exchangeTwoProjectOrganizationNodeSort(dozerUtil.convertor(twoProjectOrganizationNodeRequest.getProjectOrganizationPartOne(), ProjectOrganizationCommand.class),
                dozerUtil.convertor(twoProjectOrganizationNodeRequest.getProjectOrganizationPartTwo(), ProjectOrganizationCommand.class));

        return this.getProjectOrganizationTreeRootIsProjectOrganization(twoProjectOrganizationNodeRequest.getProjectOrganizationId());
    }

    @Override
    public ResponseData<List<ProjectOrganizationResponse>> getAllProjectOrganizationList() {
        List<ProjectOrganizationVo> projectOrganizationVos = projectOrganizationQueryService.getAllProjectOrganizationList();

        List<ProjectOrganizationResponse> projectOrganizationResponses = dozerUtil.convertor(projectOrganizationVos, ProjectOrganizationResponse.class);

        return new ResponseData<>().success(projectOrganizationResponses);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<String>> getQueryProjectOrganizationsByProjectId(Long projectId) {
        List<String> strings = new ArrayList<>();
        List<ProjectOrganizationVo> list = projectOrganizationQueryService.queryProjectOrganizationsByProjectId(projectId);
        if (null != list && list.size() > 0) {
            for(ProjectOrganizationVo projectOrganizationVo:list){
                strings.add(projectOrganizationVo.getFullName());
            }
        }
        return new ResponseData<>().success(strings);
    }

    @Override
    public ResponseData<List<ProjectOrganizationResp>> getProjectOrganizationList(ProjectOrganizationListQueryRequest projectOrganizationListQueryRequest) {
        ProjectOrganizationListQueryCommand projectOrganizationListQueryCommand = adapterConverter.organizationListQueryRequestToProjectOrganizationListQueryCommand(projectOrganizationListQueryRequest);
        List<ProjectOrganizationModel> organizations = projectOrganizationQueryService.getProjectOrganizationList(projectOrganizationListQueryCommand);
        List<ProjectOrganizationResp> organizationResps = adapterConverter.projectOrganizationsToProjectOrganizationResp(organizations);
        return new ResponseData<>().success(organizationResps);
    }
}
